// 引入内置的stream模块，获取Readable基类
const { Readable } = require('stream');

/**
 * 自定义可读流：输出a-z的26个英文字母
 * 继承Readable，需实现核心方法_read（流的数据源逻辑）
 */
class MyReadable extends Readable {
  constructor(options) {
    // 调用父类Readable的构造函数（传入配置，如编码）
    super({ ...options, encoding: 'utf8' });

    // 初始化状态：当前要输出的字符ASCII码（a的ASCII码是97）
    this.currentCode = 97;
    // 结束字符的ASCII码（z的ASCII码是122）
    this.endCode = 122;
  }

  /**
   * 核心方法：_read（Readable要求必须实现，定义如何产生数据）
   * 当流的缓冲区为空时，会自动调用_read获取新数据
   */
  _read() {
    // 判断是否已输出到z（结束条件）
    if (this.currentCode > this.endCode) {
      // push(null)：告诉流“数据已全部输出，流结束”
      this.push(null);
      return;
    }

    // 将ASCII码转为对应的字符（如97→'a'）
    const char = String.fromCharCode(this.currentCode);
    // push(char)：将数据推入流的缓冲区，供下游读取
    this.push(char);

    // 准备下一个字符的ASCII码
    this.currentCode++;
  }
}

// 1. 创建自定义可读流实例
const myReadableStream = new MyReadable();

// 2. 管道连接：自定义流 → 标准输出流（控制台）
// 也可通过on('data')监听数据事件，此处用pipe更简洁
myReadableStream.pipe(process.stdout);

// 3. 监听流结束事件，提示完成
myReadableStream.on('end', () => {
  // 换行，使控制台输出更整洁
  console.log('\n✅ 自定义流已完成a-z字符输出');
});

// 监听错误事件
myReadableStream.on('error', (err) => {
  console.error('❌ 自定义流错误：', err.message);
});